Flex 4 水平 / 垂直 反転スライダーコンポーネント
日々のお仕事シリーズ(仮称)
Flex 4 には、HSlider ( 水平 )、VSlider ( 垂直 )と、2 種類のスライダーコンポーネントが用意されていますが、最大値から最大値への進行方向がそれぞれ固定されています。 ( HSlider : 左→右、VSlider : 下→上 )
稀に、逆方向に値が増減するモノを求められることがあるのですが、そのような機能は実装されていないので、自前で用意します。
反転機能付き水平スライダーコンポーネント (ReverseHSlider.as)
package jp.classmethod.component { import flash.events.KeyboardEvent; import flash.geom.Matrix; import flash.ui.Keyboard; import spark.components.HSlider; /** * <p>ReverseHSlider クラスは、オリジナルの HSlider を水平方向に反転させたコンポーネントです。</p> * @author hirohata.taiga */ public class ReverseHSlider extends HSlider { /** * <p>水平方向の反転の有無を示すブール値です。</p> */ public function get isReverse():Boolean { return _isReverse; } /** @private */ public function set isReverse(value:Boolean):void { _isReverse = value; invalidateProperties(); invalidateDisplayList(); } /** @private */ private var _isReverse:Boolean; /** * <p>コンストラクタ</p> */ public function ReverseHSlider() { super(); } /** @private */ protected override function keyDownHandler(event:KeyboardEvent):void { var keyCode_:int = event.keyCode; if(keyCode_ == Keyboard.LEFT && _isReverse) { keyCode_ = Keyboard.RIGHT; } else if(keyCode_ == Keyboard.RIGHT && _isReverse) { keyCode_ = Keyboard.LEFT; } else if(keyCode_ == Keyboard.DOWN && _isReverse) { keyCode_ = Keyboard.UP; } else if(keyCode_ == Keyboard.UP && _isReverse) { keyCode_ = Keyboard.DOWN; } event.keyCode = keyCode_; super.keyDownHandler(event); } /** @private */ protected override function updateDisplayList(w:Number, h:Number):void { super.updateDisplayList(w, h); var m:Matrix = new Matrix(); m.scale(_isReverse ? -1 : 1, 1); m.tx = _isReverse ? unscaledWidth : 0; transform.matrix = m; } } }
反転機能付き垂直スライダーコンポーネント (ReverseVSlider.as)
package jp.classmethod.component { import flash.events.KeyboardEvent; import flash.geom.Matrix; import flash.ui.Keyboard; import spark.components.VSlider; /** * <p>ReverseVSlider クラスは、オリジナルの VSlider を垂直方向に反転させたコンポーネントです。</p> * @author hirohata.taiga */ public class ReverseVSlider extends VSlider { /** * <p>垂直方向の反転の有無を示すブール値です。</p> */ public function get isReverse():Boolean { return _isReverse; } /** @private */ public function set isReverse(value:Boolean):void { _isReverse = value; invalidateProperties(); invalidateDisplayList(); } /** @private */ private var _isReverse:Boolean; /** * <p>コンストラクタ</p> */ public function ReverseVSlider() { super(); } /** @private */ protected override function keyDownHandler(event:KeyboardEvent):void { var keyCode_:int = event.keyCode; if(keyCode_ == Keyboard.LEFT && _isReverse) { keyCode_ = Keyboard.RIGHT; } else if(keyCode_ == Keyboard.RIGHT && _isReverse) { keyCode_ = Keyboard.LEFT; } else if(keyCode_ == Keyboard.DOWN && _isReverse) { keyCode_ = Keyboard.UP; } else if(keyCode_ == Keyboard.UP && _isReverse) { keyCode_ = Keyboard.DOWN; } event.keyCode = keyCode_; super.keyDownHandler(event); } /** @private */ protected override function updateDisplayList(w:Number, h:Number):void { super.updateDisplayList(w, h); var m:Matrix = new Matrix(); m.scale(1, _isReverse ? -1 : 1); m.ty = _isReverse ? unscaledHeight : 0; transform.matrix = m; } } }
実装コード (Main.mxml)
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx = "http://ns.adobe.com/mxml/2009" xmlns:s = "library://ns.adobe.com/flex/spark" xmlns:c = "jp.classmethod.component.*" fontSize = "20" > <s:VGroup width="200" verticalCenter="0" horizontalCenter="0" gap="50"> <s:ToggleButton id="tg" width="200" label="{tg.selected?'isReverse=true':'isReverse=false'}" /> <s:VGroup width="100%" horizontalAlign="center"> <s:Label id="hLabel" text="{String(hSlider.value)}" /> <c:ReverseHSlider id="hSlider" width="200" height="30" isReverse="{tg.selected}" minimum="0" maximum="10" stepSize="1" /> </s:VGroup> <s:HGroup width="100%" verticalAlign="middle" horizontalAlign="center"> <s:Label id="vLabel" width="40" text="{String(vSlider.value)}" /> <c:ReverseVSlider id="vSlider" width="30" height="200" isReverse="{tg.selected}" minimum="0" maximum="10" stepSize="1" /> </s:HGroup> </s:VGroup> </s:Application>
解説
isReverse という反転の有無を示すプロパティを用意して、描画のタイミング ( updateDisplayList() ) でプロパティの状態に応じた変換マトリックス ( 変換行列 ) を作成して、コンポーネントの Transform オブジェクトの matrix プロパティに適用させます。
これだけで反転は実現できますが、ついでに十字キー操作のお世話もしておきました。isReverse プロパティの状態に応じてイベントオブジェクトを改竄 ( 上下左右を反転 ) しています。
出力結果
出力結果は次の通り
[SWF]http://public-blog-dev.s3.amazonaws.com/wp-content/uploads/2012/02/ReverseSliderSample20120207.swf,640,480[/SWF]